#!/bin/bash
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -e
set +e
echo -e "\n\033[32m\t*********Welcome to sharekit thirdparty!*********\033[0m\n"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

ROOT_DIR=$(pwd)
ROOT_INSTALL=${ROOT_DIR}/lib_install
ROOT_OUTPUT=${ROOT_DIR}/out
TARGET_ARCH=aarch64-linux-gnu

usage() {
    cat << EOF
    Sharekit third party 交叉编译脚本

    用法: $0 [选项]

    选项:
    --target=aarch64-linux-gnu          
                           支持: aarch64-linux-gnu(默认), arm-linux-gnueabihf,
                                arm-linux-gnueabi, etc
    --clean                清理编译文件
    --help                 显示此帮助信息


    示例:
    # 交叉编译 AArch64 三方库
    $0 --target=aarch64-linux-gnu

    # 交叉编译 ARM 三方库
    $0 --target=arm-linux-gnueabihf

    
    # 删除三方库
    $0 --clean
EOF
}

clean_build() {
    echo "=== 清理编译文件 ==="
    rm -rf ${ROOT_OUTPUT}
    rm -rf ${ROOT_INSTALL}
    echo "=== 清理完成 ==="
}

check_command_line() {
    while [ $# -gt 0 ]; do
        case $1 in
            --target=*)
                TARGET_ARCH="${1#*=}"
                ;;
            --clean)
                clean_build
                exit 0
                ;;
            --help)
                usage
                exit 0
                ;;
            *)
                echo "错误: 未知选项 $1"
                usage
                exit 1
                ;;
        esac
        shift
    done
}

check_command_line "$@"

if [[ "$TARGET_ARCH" == "aarch64-linux-gnu" ]]; then
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/aarch64
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/aarch64
elif [[ "$TARGET_ARCH" == "arm-linux-gnueabihf" ]]; then
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/arm
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/arm
else
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/aarch64
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/aarch64
fi

function check_shell_environment() {
  case $(uname -s) in 
    Linux)
          shell_result=$(/bin/sh -c 'echo ${BASH_VERSION}')
          if [ -n "${shell_result}" ]; then
            echo -e "\033[32mSystem shell: bash ${shell_result}\033[0m"
          else
            echo -e "\033[33m Your system shell isn't bash, we recommend you to use bash, because some commands may not be supported in other shells, such as pushd and shopt are not supported in dash. \n You can follow these tips to modify the system shell to bash on Ubuntu: \033[0m"
            echo -e "\033[33m [1]:Open the Terminal tool and execute the following command: sudo dpkg-reconfigure dash \n [2]:Enter the password and select <no>  \033[0m"
          fi
          ;;
    Darwin)
          echo -e "\033[31m[OHOS ERROR] Darwin system is not supported yet\033[0m"
          ;;
    *)
          echo -e "\033[31m[OHOS ERROR] Unsupported this system: $(uname -s)\033[0m"
          exit 1
  esac
}

check_shell_environment

echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32mCurrent time: $(date +%F' '%H:%M:%S)\033[0m"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32mBuild args: $@\033[0m"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

# 设置工具链
setup_toolchain() {
    echo "============ 检查交叉编译工具链 =============="
    export CC=/usr/bin/${TARGET_ARCH}-gcc
    export CXX=/usr/bin/${TARGET_ARCH}-g++
    export AR=/usr/bin/${TARGET_ARCH}-ar
    export RANLIB=/usr/bin/${TARGET_ARCH}-ranlib
    export LD=/usr/bin/${TARGET_ARCH}-ld
    export STRIP=/usr/bin/${TARGET_ARCH}-strip
}
setup_toolchain

# 检查交叉编译工具链
check_toolchain() {
    echo "============ 检查交叉编译工具链 =============="
    if ! command -v ${CC} &> /dev/null; then
        echo "错误: 交叉编译工具链 ${TARGET_ARCH} 未找到"
        echo "请安装对应的工具链:"
        echo "  Ubuntu/Debian: sudo apt install gcc-${TARGET_ARCH} g++-${TARGET_ARCH}"
        echo "  CentOS/RHEL: sudo yum install gcc-${TARGET_ARCH}-linux-gnu"
        exit 1
    fi
    echo "工具链检查通过: $(${CC} --version | head -n1)"
}
check_toolchain

compile_expat() {
    echo "============ 编译 expat ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/expat-2.5.0" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/expat-2.5.0.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/expat-2.5.0

    ./buildconf.sh
    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_dbus() {
    echo "============ 编译 dbus ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/dbus-1.15.0" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/dbus-1.15.0.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/dbus-1.15.0

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL LDFLAGS=-L$ROOT_ARCH_INSTALL/lib \
    --disable-selinux --enable-tests=no --without-x

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_ncurses() {
    echo "============ 编译 ncurses ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/ncurses-6.3" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/ncurses-6.3.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/ncurses-6.3

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL --with-shared --without-debug --disable-stripping

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_readline() {
    echo "============ 编译 readline ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/readline-8.2" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/readline-8.2.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/readline-8.2

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL LDFLAGS=-L$ROOT_ARCH_INSTALL/lib --with-shared

    make SHLIB_LIBS="-L$ROOT_ARCH_INSTALL/lib -lncurses" -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libffi() {
    echo "============ 编译 libffi ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/libffi-3.2.1" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libffi-3.2.1.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libffi-3.2.1

    ./autogen.sh
    ./configure --host=aarch64-linux --target=aarch64-linux --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_zlib() {
    echo "============ 编译 zlib ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/zlib-1.2.13" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/zlib-1.2.13.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/zlib-1.2.13

    ./configure --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libiconv() {
    echo "============ 编译 libiconv ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/libiconv-1.16" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libiconv-1.16.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libiconv-1.16

    ./configure --host=arm-linux --prefix=$ROOT_ARCH_INSTALL 

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_gettext() {
    echo "============ 编译 gettext ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/gettext-0.20" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/gettext-0.20.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/gettext-0.20

    ./configure --host=arm-linux --prefix=$ROOT_ARCH_INSTALL 

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_glib() {
    echo "============ 编译 glib ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/glib-2.58.3" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/glib-2.58.3.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/glib-2.58.3

    ./autogen.sh 
    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL CFLAGS="-fPIC -I$ROOT_ARCH_INSTALL/include" LDFLAGS=-L$ROOT_ARCH_INSTALL/lib \
    PKG_CONFIG_PATH=$ROOT_ARCH_INSTALL/lib/pkgconfig \
    LIBFFI_CFLAGS="-I$ROOT_ARCH_INSTALL/include -I$ROOT_ARCH_INSTALL/lib/libffi-3.2.1/include" \
    LIBFFI_LIBS="-L$ROOT_ARCH_INSTALL/lib -lffi" \
    ZLIB_CFLAGS="-I$ROOT_ARCH_INSTALL/include" \
    ZLIB_LIBS="-L$ROOT_ARCH_INSTALL/lib -lz" \
    --with-pcre=internal \
    --with-libiconv=gnu \
    glib_cv_stack_grows=no \
    glib_cv_have_qsort_r=yes \
    glib_cv_long_long_format=ll \
    glib_cv_uscore=no \
    glib_cv_have_strlcpy=no \
    glib_cv_va_val_copy=yes \
    glib_cv_rtldglobal_broken=no \
    ac_cv_func_posix_getpwuid_r=yes \
    ac_cv_func_posix_getgrgid_r=yes \
    ac_cv_func_printf_unix98=yes \
    ac_cv_func_vsnprintf_c99=yes \
    ac_cv_func_snprintf_c99=yes \
    ac_cv_func_nl_langinfo=yes \
    ac_cv_func_getpwuid_r=yes \
    ac_cv_func_getgrgid_r=yes \
    ac_cv_func_fallocate=yes \
    --enable-shared \
    --disable-static \
    --disable-dependency-tracking \
    --with-pcre=internal \
    --disable-libmount \
    --disable-selinux \
    --disable-xattr \
    --disable-dtrace \
    --disable-systemtap \
    --disable-gtk-doc \
    --disable-libelf \
    --disable-tests

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_bluez() {
    echo "============ 编译 bluez ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/bluez-5.63" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/bluez-5.63.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/bluez-5.63

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL \
    CFLAGS="-fPIC -I$ROOT_ARCH_INSTALL/include -I$ROOT_ARCH_INSTALL/include/glib-2.0 -I$ROOT_ARCH_INSTALL/include/dbus-1.0 " \
    LDFLAGS="-L$ROOT_ARCH_INSTALL/lib -lncurses -lreadline -ldbus-1 -lglib-2.0" \
    PKG_CONFIG_PATH=$ROOT_ARCH_INSTALL/lib/pkgconfig \
    --disable-udev \
    --disable-obex \
    --enable-library \
    --enable-experimental \
    --enable-deprecated \
    --with-dbusconfdir=$ROOT_ARCH_INSTALL/etc

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libnl() {
    echo "============ 编译 libnl ============"
    if [[ ! -f "${ROOT_DIR}/third_party/libnl-3.2.28" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libnl-3.2.28.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libnl-3.2.28

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

export CFLAGS="-I$ROOT_ARCH_INSTALL/include"
export LDFLAGS="-L$ROOT_ARCH_INSTALL/lib"

compile_openssl() {
    echo "============ 编译 gettext ============"
    if [[ ! -f "${ROOT_DIR}/third_party/openssl-1.1.1c" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/openssl-1.1.1c.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/openssl-1.1.1c

    ./Configure --prefix=$ROOT_ARCH_INSTALL  linux-aarch64 -march=armv8-a no-asm shared
   
    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

create_hostapd_config() {
    echo "创建 wpa_supplicant 配置文件..."

    cat > ".config" << EOF
    # wpa_supplicant build configuration
    CONFIG_BACKEND=file
    CONFIG_CTRL_IFACE=y
    CONFIG_CTRL_IFACE_UNIX=y
    CONFIG_DRIVER_NL80211=y
    CONFIG_DRIVER_WEXT=y
    CONFIG_IEEE80211W=y
    CONFIG_IEEE80211R=y
    CONFIG_IEEE80211N=y
    CONFIG_IEEE80211AC=y
    CONFIG_DEBUG_FILE=y
    CONFIG_PEERKEY=y
    CONFIG_TDLS=y
    CONFIG_AP=y
    CONFIG_P2P=y
    CONFIG_READLINE=y
    CONFIG_ELOOP=eloop
    CONFIG_EAPOL_TEST=y
    CONFIG_GETRANDOM=y
    CONFIG_OPTIMIZE_CFLAGS=y
EOF
}

compile_hostapd() {
    echo "============ 编译 wpa_supplicant ============"
    if [[ ! -f "${ROOT_DIR}/third_party/wpa_supplicant-2.9" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/wpa_supplicant-2.9.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/wpa_supplicant-2.9/wpa_supplicant

    create_hostapd_config

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

main() {
    if [[ ! -f "${ROOT_INSTALL}" ]]; then
        mkdir ${ROOT_INSTALL}
    fi
    if [[ ! -f "${ROOT_ARCH_INSTALL}" ]]; then
        mkdir ${ROOT_ARCH_INSTALL}
    fi
    if [[ ! -f "${ROOT_OUTPUT}" ]]; then
        mkdir ${ROOT_OUTPUT}
    fi
    if [[ ! -f "${ROOT_ARCH_OUTPUT}" ]]; then
        mkdir ${ROOT_ARCH_OUTPUT}
    fi
    
    compile_expat
    compile_dbus
    compile_ncurses
    compile_readline
    compile_libffi
    compile_zlib
    compile_libiconv
    compile_gettext
    compile_glib
    compile_bluez
    compile_libnl
    compile_openssl
    compile_hostapd
}

main "$@"

echo -e "\033[32m=====build successful=====\033[0m"
date +%F' '%H:%M:%S
echo "++++++++++++++++++++++++++++++++++++++++"
